package org.ala.tiktools.mybatis.interfaces;

import org.ala.tiktools.tools.list.Lists;

import java.util.ArrayList;
import java.util.List;

/**
 * IOrderBy的第一层实现
 *
 * @author ala
 * @date 2025-03-04 14:39
 */
public abstract class AbstractOrderBy<E> implements IOrderBy<E> {

    /**
     *  排序字段
     */
    protected List<Item> items = new ArrayList<>();
    public List<Item> getItems() {return items;}


    /**
     *  自定义排序
     */
    protected IComparator<E> comparator;
    @Override
    public int compare(E e1, E e2) {
        if (comparator != null) {
            return comparator.compare(e1, e2);
        }
        throw new RuntimeException("自定义排序要么自己实现compare()方法，要么提供comparator排序实现");
    }


    /**
     * 设置排序字段的值
     * @return
     */
    public AbstractOrderBy<E> setCurrentItemVal(E e) {
        Item item = getCurrentItem();
        item.setVal(getVal(e, item));
        return this;
    }
    /**
     *  取第一个排序字段
     */
    public Item getFirstItem() {return items.get(0);}
    /**
     *  根据字段名取值
     */
    public abstract Object getVal(E e, Item item);


    /**
     *  当前使用的是第几个排序字段
     *  <p> 从0开始
     */
    protected int itemIdx;
    /**
     *  取第i个排序字段
     *  <p> i从0开始
     */
    public Item getCurrentItem() {return items.get(itemIdx);}
    /**
     *  所有的查询条件反序
     */
    public void negateAllItems() {
        items.forEach(Item::negateAsc);
        if (!Lists.isEmpty(stationaryList)) {stationaryList.forEach(Item::negateAsc);}
    }
    /**
     *  固话的查询条件
     *  <p> 分库分表下使用
     */
    protected List<Item> stationaryList;
    public void appendStationary(Item item) {
        if (stationaryList == null) {stationaryList = new ArrayList<>();}
        //  如果item和之前的某个item字段一样，排序方式也一样，则新的覆盖老的
        for (Item _item : stationaryList) {
            if (_item.getColumn().equals(item.getColumn()) && (_item.isAsc() == item.isAsc()) && (_item.isEq() == item.isEq())) {
                _item.setVal(item.getVal());
                return;
            }
        }
        stationaryList.add(item);
    }
    public void appendStationary(Item item, E e) {
        appendStationary(item.val(getVal(e, item)));
    }
    /**
     *  临时放一下，一会还要删掉，就不合并了
     *  @param item
     */
    public void appendStationaryNoMerge(Item item) {
        if (stationaryList == null) {stationaryList = new ArrayList<>();}
        stationaryList.add(item);
    }
    public void appendStationaryNoMerge(Item item, E e) {
        appendStationaryNoMerge(item.val(getVal(e, item)));
    }
    public void removeLastStationary() {
        if (stationaryList != null && !stationaryList.isEmpty()) {
            stationaryList.remove(stationaryList.size() - 1);
            if (stationaryList.isEmpty()) {
                stationaryList = null;
            }
        }
    }

    public int getItemIdx() {
        return itemIdx;
    }

    public AbstractOrderBy<E> setItemIdx(int itemIdx) {
        this.itemIdx = itemIdx;
        return this;
    }

    public void incrItemIdx() {
        itemIdx++;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public List<Item> getStationaryList() {
        return stationaryList;
    }

    public void setStationaryList(List<Item> stationaryList) {
        this.stationaryList = stationaryList;
    }
}
